﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NLog;
using NGinnBPM.Lib.Interfaces;
using NGinnBPM.MessageBus.Impl.HttpService;
using NGinnBPM.MessageBus;
using System.IO;
using NGinnBPM.Lib.Schema;
using NGinnBPM.Lib.Data;
using System.Xml;

namespace NGinnBPM.Services.Website
{
    /// <summary>
    /// Servlet for starting process instances by 
    /// POSTing process input data in Json or Xml format.
    /// </summary>
    [UrlPattern(@"^/startprocess/(?<definition>[\w\.]+)?")]
    public class StartProcessServlet : ServletBase
    {
        public INGEnvironment Environment { get; set; }
        
        public override void HandleRequest(IRequestContext ctx)
        {
            string defid = ctx.UrlVariables["definition"];
            if (defid == null || defid.Length == 0)
                defid = ctx.QueryString["definition"];
            if (defid == null || defid.Length == 0)
                throw new Exception("Process definition ID not specified. Valid request is /startprocess/[definition id] or /startprocess/?definition=[definition id]");
            string startedby = ctx.QueryString["_startedBy"];
            string extid = ctx.QueryString["_processExternalId"];
            if (ctx.HttpMethod == "GET")
            {
                Dictionary<string, object> dob = new Dictionary<string, object>();
                foreach (string v in ctx.QueryString.Keys)
                {
                    dob[v] = ctx.QueryString[v];
                }
                string instid = Environment.StartProcess(defid, dob, startedby, extid);
                ctx.Output.Write(instid);
                return;
            }
            else if (ctx.HttpMethod == "POST")
            {
                Dictionary<string, object> dob;
                if (ctx.RequestContentType.Contains("json"))
                {
                    dob = DataUtil.ReadJson(ctx.Input);
                }
                else
                {
                    string t = ctx.Input.ReadToEnd().Trim();
                    if (t.StartsWith("<"))
                        dob = DataUtil.ReadXml(new StringReader(t));
                    else if (t.StartsWith("{"))
                        dob = DataUtil.ReadJson(new StringReader(t));
                    else throw new Exception("Unknown input format");
                }

                string instid = Environment.StartProcess(defid, dob, startedby, extid);
                ctx.Output.Write(instid);
                return;
            }
            else throw new Exception("Method not supported");
        }
    }
}
